// 【函数表达式】函数不是“神奇的语言结构”，而是一个中特殊的值。

// 创建一个函数并将其放入变量 sayHi 中（function 关键字声明的没有名字的函数称为 匿名函数）。
const sayHi = function () {
	console.log('Hello~')
}

// **********************************************************************

// 【函数是一个值】

// 无论函数是如何创建的，函数都是一个值。例如上面，变量 sayHi 是一个常量（函数值），它指向一个函数对象。

const func = sayHi
func() // Hello~

// **********************************************************************

// 【回调函数】

function ask(question, yes, no) {
	if (confirm(question)) yes()
	else no()
}

function sayYes() {
	console.log('你同意了')
}

function sayNo() {
	console.log('你不同意')
}

// 参数 sayYes 和 sayNo 可以被称为 回调函数 或简称为 回调。
ask('你同意吗?', sayYes, sayNo)

// 更好的做法是传入匿名函数，因为这样的函数在 ask 外部无法访问。
ask(
	'你同意吗?',
	function () {
		console.log('YES')
	},
	function () {
		console.log('NO')
	}
)

// **********************************************************************

// 函数声明 和 函数表达式 的区别：

// 1. 声明方式不同

// 函数声明：使用 function 关键字声明的函数，会被提升到当前作用域的顶部，可以直接调用。
// 这是内部算法的缘故。当 JavaScript 准备 运行脚本时，首先会在脚本中寻找全局函数声明，并创建这些函数。
sayHi() // Hi~

function sayHi() {
	console.log('Hi~')
}

// 函数表达式：使用变量存储一个 function 声明的函数，函数表达式是在代码执行到达时被创建，并且仅从那一刻起可用。
sayLa() // Error: sayLa is not a function

const sayLa = function () {
	console.log('La~')
}

sayLa() // La~
